package zl.applet.block;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.BoxLayout;
import javax.swing.JOptionPane;
import java.awt.GridLayout;
import java.awt.Color;
import java.awt.BorderLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent; 
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Random;

//游戏主类
public class BlockGame extends JFrame
{
	private static final long serialVersionUID = 1L;

	public static void main(String[] args)
	{
		new BlockGame();
	}

	private Canvas canvas;			//方块所在面板
	private BaseCanvas baseCanvas;	//预览面板（显示下一个方块）
	private Block block;		//方块
	private JPanel jpControl;	//控制面板
	private JTextField jtfScore,jtfLevel;
	private JButton jbPauseOrStart,jbStop,
		jbReset,jbUpLevel,jbDownLevel;
	private int score,level;
	public static final int INCREMENT = 100;	//堆满一行涨多少分
	public static final int UPGRADE = 1000;		//升级需要多少分
	public static final int MAXLEVEL = 10;		//最高多少级
	private boolean isStop;		//是否是停止状态

	//构造函数
	public BlockGame()
	{
		this.setTitle("俄罗斯方块");		//设置窗体标题
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);		//设置窗体的默认关闭操作
		this.setSize(300,400);		//设置窗体大小
		this.setLocation(		//定位窗体到屏幕中央
			this.getToolkit().getScreenSize().width / 2 - this.getWidth() / 2,
			this.getToolkit().getScreenSize().height / 2 - this.getHeight() / 2
		);

		this.jpControl = new JPanel(new GridLayout(3,1,10,10));	//控制面板
		this.canvas = new Canvas(20,12,Color.black,Color.orange,this);	//初始化方块所在面板（20行、12列）
		
		this.jtfScore = new JTextField(Integer.toString(this.score));	//显示评分
		this.jtfScore.setEnabled(false);				//不可编辑
		this.jtfLevel = new JTextField(Integer.toString(this.level));	//显示等级
		this.jtfLevel.setEnabled(false);				//不可编辑
		this.jbPauseOrStart = new JButton("Pause/Start");	//暂停/开始按钮
		this.jbStop = new JButton("Stop");		//停止、按钮
		this.jbUpLevel = new JButton("UpLevel");	//下一级别按钮
		this.jbDownLevel = new JButton("DownLevel");	//上一级别按钮
		this.jbReset = new JButton("Reset");	//重来按钮

		//给对应按钮添加单击事件
		
		//暂停、开始。按钮
		this.jbPauseOrStart.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e)
			{
				//当单击暂停开始按钮是。如果是停止状态、则先重置。然后开始
				if(isStop)
				{
					canvas.reset();
					baseCanvas.reset();
					new Thread(new Game()).start();
					isStop = false;
					jbStop.setEnabled(true);
				}
				else
					block.setPausing(!block.getPausing());		//如果暂停则开始、如果开始则暂停
				isPlay(true);		//设置正在游戏
			}
		});
		//停止。按钮
		this.jbStop.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e)
			{
				jbStop.setEnabled(false);	//单击停止按钮后。停止按钮不可用
				isStop = true;		//设置为停止状态
				isPlay(false);		//非游戏状态
			}
		});
		//下一级按钮
		this.jbUpLevel.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e)
			{
				upLevel();
			}
		});
		//上一级按钮
		this.jbDownLevel.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e)
			{
				downLevel();	
			}
		});
		//重置按钮
		this.jbReset.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e)
			{
				reset();
			}
		});


		//一下为一些布局操作
		this.baseCanvas = new BaseCanvas(Block.BOXES_ROWS,Block.BOXES_COLS,
			Color.DARK_GRAY ,Color.orange);
		JPanel temp = new JPanel();
		temp.setLayout(new BoxLayout(temp,BoxLayout.PAGE_AXIS));
		temp.add(new JLabel("The Next"));
		temp.add(this.baseCanvas);
		this.jpControl.add(temp);
		temp = new JPanel(new GridLayout(4,1));
		temp.add(new JLabel("Score"));
		temp.add(this.jtfScore);
		temp.add(new JLabel("Level"));
		temp.add(this.jtfLevel);
		this.jpControl.add(temp);
		temp = new JPanel(new GridLayout(5,1));
		temp.add(this.jbPauseOrStart);
		temp.add(this.jbStop);
		temp.add(this.jbUpLevel);
		temp.add(this.jbDownLevel);
		temp.add(this.jbReset);
		this.jpControl.add(temp);

		this.getContentPane().add(this.canvas,BorderLayout.CENTER);
		this.getContentPane().add(this.jpControl,BorderLayout.EAST);
		//给该窗体添加键盘监听事件、
		this.addKeyListener(new KeyAdapter(){
			public void keyPressed(KeyEvent e)
			{
				if(block == null)
					return;
				switch(e.getKeyCode())
				{
					case KeyEvent.VK_UP:	//键盘上键
						turning();
						break;
					case KeyEvent.VK_DOWN:	//键盘下键
						block.moveDown();
						break;
					case KeyEvent.VK_LEFT:
						block.moveLeft();
						break;
					case KeyEvent.VK_RIGHT:
						block.moveRight();
						break;
					case KeyEvent.VK_SPACE:
						block.setPausing(!block.getPausing());
						break;
					default:
						break;
				}
			}
		});

		this.addComponentListener(new ComponentAdapter() {
			public void componentResized(ComponentEvent e) 
			{
				canvas.fanning();
				baseCanvas.fanning();
			}
		});

		this.addWindowListener(new WindowAdapter() {
			public void windowIconified(WindowEvent e) 
			{
				block.setPausing(!block.getPausing());	//窗体最小化时暂停
			}
			public void windowDeiconified(WindowEvent e)
			{
				windowIconified(e);
			}
		});

		this.setVisible(true);	//显示窗体
		new Thread(new Game()).start();		//开始游戏
		this.isPlay(true);	//设置开始游戏
	}

	//设置评分
	public void setScore(int score)
	{
		this.score = score;
		if(((this.score / BlockGame.UPGRADE) + this.level) >= BlockGame.MAXLEVEL)
			this.level = BlockGame.MAXLEVEL;
		else
			this.level = (this.score / BlockGame.UPGRADE) + this.level;
		this.jtfScore.setText(Integer.toString(this.score));
		this.jtfLevel.setText(Integer.toString(this.level));
	}
	public int getScore()
	{
		return this.score;
	}

	//切换方块样式
	public void turning()
	{
		if(this.block == null)
			return;
		for(int i = 0; i < Block.STYLES.length; i++)
		{
			for(int j = 0; j < Block.STYLES[i].length; j++)
			{
				if(Block.STYLES[i][j] == this.block.getStyle())
				{
					this.block.turnTo(Block.STYLES[i][(j + 1) % Block.STYLES[i].length]);
					break;
				}
			}
		}
	}

	//重置
	public void reset()
	{
		this.canvas.reset();
		this.baseCanvas.reset();
		this.score = 0;
		this.level = 0;
		this.jtfScore.setText(Integer.toString(this.score));
		this.jtfLevel.setText(Integer.toString(this.level));
	}

	//结束游戏
	public void gameOver()
	{
		jbStop.setEnabled(false);
		JOptionPane.showMessageDialog(this,"GameOver！！！","消息",JOptionPane.INFORMATION_MESSAGE);
		this.isPlay(false);
	}

	public void upLevel()
	{
		this.level = this.level++ >= BlockGame.MAXLEVEL ? BlockGame.MAXLEVEL : this.level;
		this.jtfLevel.setText(Integer.toString(this.level));
	}

	public void isPlay(boolean state)
	{
		this.jbReset.setEnabled(!state);
		this.jbUpLevel.setEnabled(!state);
		this.jbDownLevel.setEnabled(!state);
	}

	public void downLevel()
	{
		this.level = this.level-- <= 0 ? 0 : this.level;
		this.jtfLevel.setText(Integer.toString(this.level));
	}

	//游戏类
	private class Game implements Runnable
	{
		private Random random = new Random();
		public void run()
		{
			int col = 5;
			//随机出样式
			int style = Block.STYLES[this.random.nextInt(7)]
					[this.random.nextInt(4)];
			while(true)
			{
				requestFocus();
				if(block != null)
				{
					if(isStop)
					{
						block.setPausing(true);
						block = null;
						return;
					}
					if(block.isAlive())
						continue;
				}
				canvas.removeFullLine();	//移除堆满的行
				if(!canvas.checkState())	//检测有没有堆到顶部
				{
					gameOver();
					return;
				}
				//新建一个方块
				block = new Block(style,0,col,level,canvas);
				//方块开始运动
				block.start();
				col = random.nextInt(canvas.getCols() - 6) + 3;
				//随机产生方块样式
				style = Block.STYLES[this.random.nextInt(7)]
					[this.random.nextInt(4)];
				try
				{
					Thread.sleep(3000);
					baseCanvas.setStyle(style);
				}
				catch (InterruptedException e)
				{
					e.printStackTrace();
				}	
			}
		}
	}
}